/**
 * 云静表单
 */
layui.use(['jquery', 'yunj', 'element', 'elemProgress', 'button', 'dropdown', "validate"], function () {
    let win = window;
    let doc = document;
    let $ = layui.jquery;
    let element = layui.element;
    let elemProgress = layui.elemProgress;
    let button = layui.button;
    let dropdown = layui.dropdown;
    let validate = layui.validate;

    class YunjForm {

        constructor(obj) {
            this.version = '1.0.0';                 // 版本号

            this.id = obj.id;                         // 当前对象id

            this.raw_el = obj.elem;                   // 原始元素

            this.raw_args = obj.args;                 // 原始数据

            this.box_el = null;                       // 顶部父元素

            this.header_box_el = null;                // 表单header元素

            this.tab_box_el = null;                   // 表单选项卡父元素

            this.url = null;                          // 请求地址

            this.url_param = null;                    // url参数

            this.isPopup = false;                    // 是否弹出层

            this.raw_page_win = null;                 // 来源页面window对象

            this.raw_table = null;                    // 来源表格

            this.tab_title_el = null;                 // 当前tab标题元素

            this.tab = null;                        // 当前tab

            this.tab_content_el = null;               // 当前tab内容元素

            this.vals = {};                           // 表单字段值

            this.fields = {};                         // 表单字段实例容器

            this.elemProgress = null;              // 表单加载进度对象

            this.init();
        }

        init() {
            let that = this;
            if (!that.id || !that.raw_args || win.yunj.isEmptyObj(that.raw_args)) return false;
            // 初始化布局
            that.init_layout();
            // 设置数据
            that.set_data();
            // 进度0
            that.elemProgress = elemProgress({elem: that.box_el.hasClass('header-fixed') ? that.box_el.find('.progress') : that.box_el});
            // 渲染
            that.render().then(res => {
                // 设置事件绑定
                that.set_event_bind();
                // 进度100%
                that.elemProgress.reset_progress(100);
            });
        }

        // 初始化布局
        init_layout() {
            let that = this;
            let extraClass = that.raw_el.attr('class');
            extraClass = yunj.isUndefined(extraClass) ? '' : extraClass;
            let headerFixed = $('form[type=yunj]').length === 1 && extraClass.indexOf('header-fixed') >= 0;

            let layout = `<div class="layui-card yunj-form-box ${headerFixed ? 'header-fixed' : ''}" lay-filter="${that.id}" >
                            <div class="layui-card-body">
                                ${headerFixed ? '<div class="progress"></div>' : ''}
                                <div class="yunj-form-header">
                                    <div class="partition"></div>
                                    <div class="content">
                                        <h2></h2>
                                        <div class="btn-box"></div>
                                    </div>
                                </div>
                                <div class="layui-tab" lay-filter="${that.id}_tab"></div>
                            </div>
                        </div>`;
            that.raw_el.after(layout);
        }

        // 设置数据
        set_data() {
            let that = this;
            let id = that.id;
            let raw_args = that.raw_args;
            that.box_el = $(`.yunj-form-box[lay-filter=${id}]`);
            that.header_box_el = that.box_el.find(`.yunj-form-header`);
            that.tab_box_el = that.box_el.find(`.layui-tab[lay-filter=${id}_tab]`);

            that.url = raw_args.hasOwnProperty('url') ? raw_args.url : yunj.url(false);
            that.url_param = yunj.urlParam(null, {});
            that.isPopup = that.url_param.hasOwnProperty('isPopup') && that.url_param.isPopup === 'yes';

            that.raw_page_win = yunj.rawPageWin();
            if (that.raw_page_win && that.url_param.hasOwnProperty('raw_table'))
                that.raw_table = that.raw_page_win.yunj.table[that.url_param.raw_table];

        }

        // 渲染
        async render() {
            let that = this;
            that.render_title();
            that.render_tab();
            await that.render_fields();
            that.render_button();
            // 表单渲染完成事件触发
            $(doc).trigger(`yunj_form_${that.id}_render_done`);
            return 'done';
        }

        // 渲染标题
        render_title() {
            let that = this;
            let title = yunj.currPageTitle(that.isPopup);
            if (title.length > 0) that.header_box_el.find('.content h2').html(title);
        }

        // 渲染表单选项卡
        render_tab() {
            let that = this;
            if (that.tab_box_el.find('.layui-tab-title').length > 0) return true;
            let tabs = that.raw_args.tab;
            let titleHtml = '';
            let contentHtml = '';
            let i = 0;
            for (let tab in tabs) {
                if (!tabs.hasOwnProperty(tab)) continue;
                titleHtml += `<li class="${i === 0 ? 'layui-this' : ''}" data-tab="${tab}">${tabs[tab]}</li>`;
                contentHtml += `<div class="layui-tab-item ${i === 0 ? 'layui-show' : ''}">
                                    <form class="layui-form layui-form-pane yunj-form yunj-tab-${tab}" lay-filter="${that.id}_${tab}"></form>
                                </div>`;
                i++;
            }
            titleHtml = `<ul class="layui-tab-title">${titleHtml}</ul>`;
            contentHtml = `<div class="layui-tab-content">${contentHtml}</div>`;
            let tabHtml = titleHtml + contentHtml;
            that.tab_box_el.html(tabHtml);
            that.set_tab_data();
        }

        // 设置表单选项卡值
        set_tab_data() {
            let that = this;
            that.tab_title_el = that.tab_box_el.find(`.layui-tab-title li.layui-this`);
            that.tab = that.tab_title_el.data("tab");
            that.tab_content_el = that.tab_box_el.find(`.layui-tab-content .layui-tab-item.layui-show`);
        }

        // 渲染字段
        async render_fields() {
            let that = this;
            await that.set_form_vals();
            await that.render_fields_handle();
            that.set_fields_label_layout();
            return 'done';
        }

        // 设置表单字段值
        set_form_vals() {
            let that = this;
            return new Promise(resolve => {
                if (!that.raw_args.load) {
                    that.vals = {};
                    resolve('done');
                    return;
                }
                yunj.request({
                    url: that.url,
                    data: {builder_id: that.id, builder_async_type: 'load'},
                    eventTitle: '表单字段值查询',
                    loading: {enable: false},
                    successCallback: function (requestArgs, responseRes) {
                        that.vals = responseRes.data;
                        resolve('done');
                    },
                });
            });
        }

        // 渲染字段处理
        async render_fields_handle() {
            let that = this;
            let vals = that.vals;
            for (let tab in that.raw_args.tab) {
                if (!that.raw_args.tab.hasOwnProperty(tab)) continue;
                let fields = that.raw_args.field[tab];
                for (let key in fields) {
                    if (!fields.hasOwnProperty(key)) continue;
                    let args = fields[key];
                    // args.value
                    if (yunj.isObj(vals) && !yunj.isEmptyObj(vals)) {
                        args.value = vals[key];
                        delete vals[key];
                    }

                    await new Promise(resolve => {
                        yunj.formField(args.type, {
                            formId: that.id,
                            tab: tab,
                            key: key,
                            args: args,
                        }).then(field => {
                            field.render(`.layui-tab[lay-filter=${that.id}_tab] .layui-tab-content .yunj-tab-${tab}`).then(res => {
                                that.fields[field.id] = field;
                                resolve(`${key} done`);
                            });
                        });
                    });
                }
            }
            return 'done';
        }

        // 设置表单字段label布局
        set_fields_label_layout() {
            let that = this;
            let labelMaxWidth = 0;
            let formItemEl = that.tab_content_el.find('.yunj-form-item:not(.layui-form-textarea):not(.yunj-form-editor):not(.yunj-form-markdown):not(.yunj-form-imgs)');
            formItemEl.each(function () {
                let currLabelWidth = $(this).find('.layui-form-label').outerWidth();
                if (currLabelWidth > labelMaxWidth) labelMaxWidth = currLabelWidth;
            });
            let inc = 1;
            formItemEl.find('.layui-form-label').css('width', labelMaxWidth + inc + 'px');
        }

        // 渲染按钮
        render_button() {
            let that = this;

            if (!that.raw_args.hasOwnProperty('button')) return false;
            let btnBoxEl = that.header_box_el.find('.btn-box');
            let btnBoxHtml = btnBoxEl.html();
            let outbtnArr = [];
            let currWidth = $(doc).width();
            if (currWidth < 375) {
                outbtnArr = ['submit'];
            } else if (currWidth >= 375 && currWidth <= 480) {
                outbtnArr = ['back', 'submit', 'reset'];
            }
            let outbtnArrLen = outbtnArr.length;
            if (outbtnArrLen <= 0 && btnBoxHtml.length > 0) return false;

            btnBoxEl.html('');
            let ddHtml = '';
            let btnArr = that.raw_args.button;
            for (let i in btnArr) {
                if (!btnArr.hasOwnProperty(i)) continue;
                let type = btnArr[i];
                if (!button.hasOwnProperty(type)) continue;
                if (outbtnArrLen <= 0 || outbtnArr.indexOf(type) !== -1) {
                    button[type](that.id).render(`.yunj-form-box[lay-filter=${that.id}] .yunj-form-header .btn-box`);
                } else {
                    ddHtml += button[type](that.id).layout(true);
                }
            }
            if (ddHtml.length > 0) {
                let dropdownLayout = dropdown.layout(ddHtml);
                btnBoxEl.append(dropdownLayout);
            }
            return true;
        }

        // 切换选项卡
        tab_change() {
            let that = this;
            that.set_tab_data();
            that.set_fields_label_layout();
            that.set_fields_markdown_editormd_reload();
        }

        // 设置字段 type=markdown mode=editormd 的字段重新加载
        set_fields_markdown_editormd_reload() {
            let that = this;
            let fields = that.raw_args.field[that.tab];
            for (let k in fields) {
                if (!fields.hasOwnProperty(k)) continue;
                if (fields[k].type !== "markdown" || (fields[k].hasOwnProperty("mode") && fields[k].mode !== "editormd")) continue;
                let fieldObj = that.fields[`${that.id}_${that.tab}_${k}`];
                fieldObj.reload_editormd();
            }
        }

        // 验证数据
        verify_data(data, tab_data) {
            let that = this;
            let verifyRule = {};            // 验证规则
            let verifyData = {};            // 验证数据
            let verifyDataTitle = {};       // 验证数据title
            // 组合验证参数
            let tabFields = that.raw_args.field;
            for (let tab in tabFields) {
                if (!tabFields.hasOwnProperty(tab) || !tab_data.hasOwnProperty(tab)) continue;
                let fields = tabFields[tab];
                for (let k in fields) {
                    if (!fields.hasOwnProperty(k) || !tab_data[tab].hasOwnProperty(k)) continue;
                    let field = fields[k];
                    if (field.verify.length <= 0) continue;
                    let fieldVerifyKey = `${tab}_${k}`;
                    verifyRule[fieldVerifyKey] = field.verify;
                    verifyData[fieldVerifyKey] = tab_data[tab][k];
                    verifyDataTitle[fieldVerifyKey] = field.title;
                }
            }
            // 验证
            validate.create({
                rule: verifyRule,
                ignore_rule_exist: true
            });
            validate.checkTips(verifyData, verifyDataTitle);
            return true;
        }

        // 设置事件绑定
        set_event_bind() {
            let that = this;

            // 窗口大小发生变化时触发
            $(win).resize(function () {
                that.render_button();
            });

            // 监听tab切换
            element.on(`tab(${that.id}_tab)`, function (data) {
                that.tab_change();
            });

            // 监听return点击
            that.box_el.on('click', '.yunj-btn-return', function () {
                yunj.closeCurr();
            });

            // 监听reload点击
            that.box_el.on('click', '.yunj-btn-reload', function () {
                location.reload(true);
            });

            // 监听reset点击
            that.box_el.on('click', '.yunj-btn-reset', function () {
                $(doc).trigger(`yunj_form_${that.id}_reset`);
            });

            // 监听clear点击
            that.box_el.on('click', '.yunj-btn-clear', function () {
                $(doc).trigger(`yunj_form_${that.id}_clear`);
            });

            // 监听submit点击
            that.box_el.on('click', '.yunj-btn-submit', function () {
                let [formData, formTabData] = yunj.formData(that.id, true);
                that.verify_data(formData, formTabData);
                if (yunj.isEmptyObj(formData) || yunj.isEmptyObj(formTabData)) return false;
                let requestData = {
                    builder_id: that.id,
                    builder_async_type: 'submit',
                    data: JSON.stringify(formData),
                    tab_data: JSON.stringify(formTabData)
                };
                yunj.request({
                    url: that.url,
                    data: requestData,
                    eventTitle: '表单提交',
                    successCallback: function (requestArgs, responseRes) {
                        let response_data = responseRes.data;
                        // 来源页面
                        if (yunj.isObj(response_data) && response_data.hasOwnProperty('reload') && response_data.reload) {
                            if (that.raw_table) {
                                that.raw_table.render();
                            } else if (that.raw_page_win) {
                                that.raw_page_win.location.reload(true);
                            }
                        }
                        // 关闭弹出层
                        if (that.isPopup) yunj.closeCurr();
                        return false;
                    },
                });
            });
        }

    }

    $(doc).ready(function () {
        win.yunj.form = {};

        let formEls = $('form[type=yunj]');
        if (yunj.isEmptyObj(YUNJ_FORM) || formEls.length <= 0) return false;
        formEls.each(function () {
            let id = $(this).attr('id');
            if (!YUNJ_FORM.hasOwnProperty(id)) return true;
            let args = YUNJ_FORM[id];
            win.yunj.form[id] = new YunjForm({
                id: id,
                elem: $(this),
                args: args
            });
        });
    });

});